<script setup lang="ts">
import { computed, ref } from 'vue'
import AddRecord from './AddRecord.vue'
import { ElDatePicker, ElMessage } from 'element-plus'
import VoiceRecord from './VoiceRecord.vue'
import { FinanceService } from '/@/api/openapi'

const props = defineProps<{
  records: Array<{
    id: number
    name: string
    type: string
    category: string
    date: string
    amount: number
    remark?: string
  }>
  startTime: string
  endTime: string
  showAddForm: { [key: string]: boolean }
}>()

const emit = defineEmits([
  'toggle-add-form',
  'add-success',
  'update-record',
  'delete-record',
  'date-range-change',
])

// 默认显示上个月和这个月
const defaultDateRange = (): [string, string] => {
  const now = new Date()
  const end = new Date()
  const start = new Date(now.getFullYear(), now.getMonth() - 1, 1)
  return [start.toISOString().split('T')[0], end.toISOString().split('T')[0]]
}

const dateRange = ref<[string, string]>(defaultDateRange())

// 处理日期范围变化
const handleDateRangeChange = (dates: [string, string]) => {
  console.log('dateRangeChange', dates)
  if (dates) {
    dateRange.value = dates
    emit('date-range-change', {
      startDate: dates[0],
      endDate: dates[1],
    })
  }
}

// 获取日期范围内的所有日期
const getDatesInRange = computed(() => {
  const dates: string[] = []
  const start = new Date(props.startTime)
  const end = new Date(props.endTime)

  for (
    let date = new Date(start);
    date <= end;
    date.setDate(date.getDate() + 1)
  ) {
    dates.push(date.toISOString().split('T')[0])
  }

  return dates
})

// 修改分组记录的计算方式
const groupedRecords = computed(() => {
  const groups: { [key: string]: typeof props.records } = {}

  // 初始化所有日期的空数组
  getDatesInRange.value.forEach(date => {
    groups[date] = []
  })

  // 填充实际记录
  props.records.forEach(record => {
    if (groups[record.date]) {
      groups[record.date].push(record)
    }
  })

  // 将日期按倒序排列
  const sortedDates = Object.keys(groups).sort((a, b) => b.localeCompare(a))

  // 返回按倒序排列的记录
  const sortedGroups: { [key: string]: typeof props.records } = {}
  sortedDates.forEach(date => {
    sortedGroups[date] = groups[date]
  })

  return sortedGroups
})

// 处理更新记录
const handleUpdate = (record: (typeof props.records)[0]) => {
  emit('update-record', record)
}

// 处理删除记录
const handleDelete = (record: (typeof props.records)[0]) => {
  emit('delete-record', record)
}

// 获取分类样式类名
const getCategoryClass = (category: string) => {
  const categoryMap: { [key: string]: string } = {
    工资: 'salary',
    兼职: 'part-time',
    餐饮: 'food',
    购物: 'shopping',
    居住: 'housing',
    交通: 'transport',
    娱乐: 'entertainment',
    医疗: 'medical',
    教育: 'education',
    其他: 'other',
  }
  return categoryMap[category] || 'other'
}

// 添加图标样式
const getCategoryIcon = (category: string) => {
  const iconMap: { [key: string]: string } = {
    工资: 'fa-money-bill-alt',
    兼职: 'fa-briefcase',
    餐饮: 'fa-utensils',
    购物: 'fa-shopping-cart',
    居住: 'fa-home',
    交通: 'fa-car',
    娱乐: 'fa-gamepad',
    医疗: 'fa-hospital',
    教育: 'fa-graduation-cap',
    其他: 'fa-ellipsis-h',
  }
  return iconMap[category] || 'fa-tag'
}

// 添加一个方法来格式化日期并显示星期几
const formatDateWithDay = (dateString: string) => {
  const date = new Date(dateString)
  const options: Intl.DateTimeFormatOptions = {
    weekday: 'long',
    year: 'numeric',
    month: 'long',
    day: 'numeric',
  }
  return date.toLocaleDateString('zh-CN', options).replace('星期', '  星期')
}

// 添加语音录制相关的状态
const isRecording = ref(false)
const showVoiceDialog = ref<boolean>(false)
const recordedData = ref<Blob | null>(null)
const mediaRecorder = ref<MediaRecorder | null>(null)
const voiceRecognitionResult = ref<
  {
    name: string
    type: string
    category: string
    amount: number
    remark?: string
  }[]
>([])

// 开始录音
const startRecording = async () => {
  try {
    const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
    mediaRecorder.value = new MediaRecorder(stream, {
      mimeType: 'audio/mp3',
    })
    const chunks: BlobPart[] = []

    mediaRecorder.value.ondataavailable = e => {
      chunks.push(e.data)
    }

    mediaRecorder.value.onstop = async () => {
      console.log('=======录音完成====')
      recordedData.value = new Blob(chunks, { type: 'audio/mp3' })
      const formData = new FormData()
      formData.append('file', recordedData.value)

      try {
        console.log('开始识别...')
        const response = await FinanceService.automatic(formData)
        if (response.code === 200 && response.data) {
          console.log('原始数据:', response.data)
          // 转换数据格式并过滤掉无效数据
          const convertedData = (response.data || [])
            .filter(
              item =>
                item && item.name && item.type && item.category && item.amount,
            )
            .map(item => ({
              name: item.name || '',
              type: item.type || '支出',
              category: item.category || '其他',
              amount: Number(item.amount) || 0,
              remark: item.remark || '',
            }))

          if (convertedData.length > 0) {
            voiceRecognitionResult.value = convertedData
            ElMessage.success(`成功识别${convertedData.length}条记录`)
          } else {
            ElMessage.warning('未能识别出有效的记录')
          }
        } else {
          console.log(response.message)
          ElMessage.error(response.message || '识别失败')
        }
      } catch (error) {
        console.error('语音识别失败:', error)
        ElMessage.error('语音识别失败')
      }
    }

    mediaRecorder.value.start()
    isRecording.value = true
  } catch (err) {
    console.error('无法访问麦克风:', err)
    ElMessage.error('无法访问麦克风')
  }
}

// 停止录音
const stopRecording = () => {
  if (mediaRecorder.value && isRecording.value) {
    mediaRecorder.value.stop()
    isRecording.value = false
    mediaRecorder.value.stream.getTracks().forEach(track => track.stop())
  }
}

// 确认添加记录
const confirmVoiceRecord = (date: string) => {
  if (voiceRecognitionResult.value && voiceRecognitionResult.value.length > 0) {
    // 遍历所有识别出的账单记录，逐个添加
    voiceRecognitionResult.value.forEach(record => {
      emit('add-success', {
        ...record,
        date,
      })
    })
    showVoiceDialog.value = false
    voiceRecognitionResult.value = []
  }
}

// 添加状态
const currentDate = ref('')

// 处理打开语音录入
const handleOpenVoiceRecord = (date: string) => {
  currentDate.value = date
  showVoiceDialog.value = true
}
</script>

<template>
  <div class="day-view">
    <!-- 添加日期范围选择器 -->
    <div class="date-range-picker">
      <el-date-picker
        v-model="dateRange"
        type="daterange"
        range-separator="至"
        start-placeholder="开始日期"
        end-placeholder="结束日期"
        format="YYYY-MM-DD"
        value-format="YYYY-MM-DD"
        :default-value="defaultDateRange()"
        @change="handleDateRangeChange"
      />
    </div>

    <div
      v-for="(dayRecords, date) in groupedRecords"
      :key="date"
      class="day-group"
    >
      <div class="date-header">
        <div class="date-info">
          <h3>{{ formatDateWithDay(date) }}</h3>
          <div class="daily-summary">
            <span class="income-text"
              >收入: ¥{{
                dayRecords
                  .filter(r => r.type === '收入')
                  .reduce((sum, r) => sum + r.amount, 0)
              }}</span
            >
            <span class="expense-text"
              >支出: ¥{{
                dayRecords
                  .filter(r => r.type === '支出')
                  .reduce((sum, r) => sum + r.amount, 0)
              }}</span
            >
          </div>
        </div>
        <div class="button-group">
          <button
            v-if="!showAddForm[date]"
            class="add-button"
            @click="emit('toggle-add-form', date)"
          >
            + 新增记录
          </button>
          <button
            v-if="!showAddForm[date]"
            class="voice-button"
            @click="handleOpenVoiceRecord(date)"
          >
            <i class="fa fa-microphone"></i> 智能录入
          </button>
        </div>
      </div>

      <AddRecord
        v-if="showAddForm[date]"
        :date="date"
        @add-success="
          record => {
            emit('add-success', record)
            $refs[`addRecord${date}`].resetForm()
          }
        "
        ref="addRecord"
      />

      <div class="records">
        <div class="record-header">
          <span class="col name">名称</span>
          <span class="col type">类型</span>
          <span class="col category">种类</span>
          <span class="col date">日期</span>
          <span class="col remark">备注</span>
          <span class="col spacer"></span>
          <span class="col amount">金额</span>
          <span class="col actions">操作</span>
        </div>

        <!-- 如果没有记录，显示空状态 -->
        <div v-if="dayRecords.length === 0" class="empty-state">
          <p>暂无记录</p>
        </div>

        <!-- 有记录时显示记录列表 -->
        <template v-else>
          <div
            v-for="record in dayRecords"
            :key="record.id"
            class="record-item"
          >
            <span class="col name">{{ record.name }}</span>
            <span class="col type">
              <span
                class="type-tag"
                :class="record.type === '收入' ? 'income' : 'expense'"
              >
                <i
                  :class="
                    record.type === '收入'
                      ? 'fa fa-plus-circle'
                      : 'fa fa-minus-circle'
                  "
                ></i>
                <span class="type-text">{{ record.type }}</span>
              </span>
            </span>
            <span class="col category">
              <span
                class="category-tag"
                :class="getCategoryClass(record.category)"
              >
                <i :class="'fa ' + getCategoryIcon(record.category)"></i>
                <span class="category-text">{{ record.category }}</span>
              </span>
            </span>
            <span class="col date">{{ record.date }}</span>
            <span class="col remark" :title="record.remark">{{
              record.remark || '-'
            }}</span>
            <span class="col spacer"></span>
            <span
              class="col amount"
              :class="record.type === '收入' ? 'income' : 'expense'"
            >
              {{ record.type === '收入' ? '+' : '-' }}¥{{ record.amount }}
            </span>
            <span class="col actions">
              <button
                class="action-button update"
                @click="handleUpdate(record)"
              >
                <i class="fa fa-edit"></i>
              </button>
              <button
                class="action-button delete"
                @click="handleDelete(record)"
              >
                <i class="fa fa-trash"></i>
              </button>
            </span>
          </div>
        </template>
      </div>
    </div>
  </div>

  <!-- 添加语音录入对话框 -->
  <VoiceRecord
    v-model:visible="showVoiceDialog"
    :date="currentDate"
    @add-success="record => emit('add-success', record)"
  />
</template>

<style scoped>
.day-view {
  width: 100%;
}

.day-group {
  margin-bottom: 24px;
  background: white;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.date-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #eee;
}

.date-info {
  display: flex;
  align-items: center;
  gap: 24px;
}

.date-info h3 {
  margin: 0;
  font-size: 18px;
  color: #333;
}

.daily-summary {
  display: flex;
  gap: 16px;
  font-size: 14px;
}

.records {
  margin-top: 16px;
}

.record-header {
  display: flex;
  padding: 8px 16px;
  background: #fafafa;
  border-radius: 4px;
  margin-bottom: 8px;
  font-weight: 500;
  color: #666;
}

.record-item {
  display: flex;
  padding: 12px 16px;
  border-bottom: 1px solid #f0f0f0;
}

.record-item:last-child {
  border-bottom: none;
}

.col {
  display: flex;
  align-items: center;
}

.col.name {
  flex: 1.5;
  padding-right: 16px;
}

.col.type {
  flex: 0.6;
  justify-content: center;
}

.col.category {
  flex: 0.8;
  justify-content: center;
}

.col.remark {
  flex: 1.5;
  color: #666;
  font-size: 14px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.col.spacer {
  width: 50px;
  flex: 0 0 50px;
}

.col.amount {
  flex: 0.8;
  justify-content: flex-end;
  font-weight: 500;
}

.type-tag {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.type-text {
  margin-left: 2px;
  color: #333;
}

.type-tag.income {
  background: rgba(82, 196, 26, 0.1);
  border: 1px solid #52c41a;
}

.type-tag.expense {
  background: rgba(245, 34, 45, 0.1);
  border: 1px solid #f5222d;
}

.income {
  color: #52c41a;
}

.expense {
  color: #f5222d;
}

.add-button {
  padding: 6px 16px;
  background: #1890ff;
  border: none;
  border-radius: 4px;
  color: white;
  cursor: pointer;
  font-size: 14px;
}

.add-button:hover {
  background: #40a9ff;
}

.category-tag {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 12px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.category-text {
  margin-left: 2px;
  color: #333;
}

/* 分类样式 */
.category-tag.salary {
  background: rgba(24, 144, 255, 0.1);
  border: 1px solid #1890ff;
}

.category-tag.part-time {
  background: rgba(114, 46, 209, 0.1);
  border: 1px solid #722ed1;
}

.category-tag.food {
  background: rgba(250, 140, 22, 0.1);
  border: 1px solid #fa8c16;
}

.category-tag.shopping {
  background: rgba(235, 47, 150, 0.1);
  border: 1px solid #eb2f96;
}

.category-tag.housing {
  background: rgba(47, 84, 235, 0.1);
  border: 1px solid #2f54eb;
}

.category-tag.transport {
  background: rgba(19, 194, 194, 0.1);
  border: 1px solid #13c2c2;
}

.category-tag.entertainment {
  background: rgba(160, 217, 17, 0.1);
  border: 1px solid #a0d911;
}

.category-tag.medical {
  background: rgba(245, 34, 45, 0.1);
  border: 1px solid #f5222d;
}

.category-tag.education {
  background: rgba(67, 67, 67, 0.1);
  border: 1px solid #434343;
}

.category-tag.other {
  background: rgba(140, 140, 140, 0.1);
  border: 1px solid #8c8c8c;
}

.col.actions {
  flex: 0.8;
  justify-content: flex-end;
  gap: 8px;
}

.action-button {
  padding: 4px 8px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 14px;
  color: white;
  transition: opacity 0.3s;
}

.action-button:hover {
  opacity: 0.8;
}

.action-button.update {
  background: #1890ff;
}

.action-button.delete {
  background: #ff4d4f;
}

.action-button i {
  font-size: 14px;
}

.empty-state {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 24px;
  color: #999;
  font-size: 14px;
  background: #fafafa;
  border-radius: 4px;
}

.empty-state p {
  margin: 0;
}

.date-range-picker {
  margin-bottom: 20px;
  display: flex;
  justify-content: flex-end;
}

:deep(.el-date-editor) {
  width: 320px;
}

.col.date {
  flex: 0.8;
  justify-content: center;
  color: #666;
  font-size: 14px;
}

/* 添加新样式 */
.button-group {
  display: flex;
  gap: 8px;
}

.voice-button {
  padding: 6px 16px;
  background: #722ed1;
  border: none;
  border-radius: 4px;
  color: white;
  cursor: pointer;
  font-size: 14px;
  display: flex;
  align-items: center;
  gap: 4px;
}

.voice-button:hover {
  background: #8c51e0;
}

.voice-dialog-content {
  padding: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 20px;
}

.recording-status {
  text-align: center;
}

.record-icon {
  width: 60px;
  height: 60px;
  border-radius: 50%;
  background: #f5f5f5;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  font-size: 24px;
  color: #666;
}

.record-icon.recording {
  background: #f56c6c;
  color: white;
  animation: pulse 1.5s infinite;
}

@keyframes pulse {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
  100% {
    transform: scale(1);
  }
}

.recognition-result {
  width: 100%;
  padding: 15px;
  background: #f8f8f8;
  border-radius: 8px;
}

.recognition-result h4 {
  margin: 0 0 10px 0;
  color: #333;
}

.result-item {
  display: flex;
  margin-bottom: 8px;
}

.result-item .label {
  width: 60px;
  color: #666;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}
</style>